
#include "hardware_model.h"
#include "simulator_sim.h"

MemFetch::MemFetch(const MemAccess &access, uint32_t ctrl_size, Instruction *ins,
                   uint32_t core_id, const MemoryConfig *config,
                   cycle_t cycle,
                   MemFetch *original_mf,
                   MemFetch *original_wr_mf)
    : m_access(access)

{
  m_pe_id = core_id;
  m_access = access;
  m_ctrl_size = ctrl_size;
  m_data_size = access.get_size();

  m_type = m_access.is_write() ? WRITE_REQUEST : READ_REQUEST;
  m_timestamp = cycle;

  m_original_mf = original_mf;
  m_original_wr_mf = original_wr_mf;

  m_mem_config = config;
  m_ins=ins;
  config->m_address_mapping.addrdec_tlx(access.get_addr(), &m_raw_addr);
  m_partition_addr =
      config->m_address_mapping.partition_address(access.get_addr());
}
MemFetch::MemFetch(const MemAccess &access, uint32_t ctrl_size,
                   uint32_t core_id, const MemoryConfig *config,
                   cycle_t cycle,
                   MemFetch *original_mf,
                   MemFetch *original_wr_mf)
    : m_access(access)

{
  m_pe_id = core_id;
  m_access = access;
  m_ctrl_size = ctrl_size;
  m_data_size = access.get_size();

  m_type = m_access.is_write() ? WRITE_REQUEST : READ_REQUEST;
  m_timestamp = cycle;

  m_original_mf = original_mf;
  m_original_wr_mf = original_wr_mf;

  m_mem_config = config;

  config->m_address_mapping.addrdec_tlx(access.get_addr(), &m_raw_addr);
  m_partition_addr =
      config->m_address_mapping.partition_address(access.get_addr());
}
MemFetch::~MemFetch()
{
}

/// Returns number of flits traversing interconnect. simt_to_mem specifies the
/// direction
uint32_t MemFetch::get_num_flits(bool simt_to_mem)
{
  uint32_t sz = 0;
  // If atomic, write going to memory, or read coming back from memory, size =
  // ctrl + data. Else, only ctrl
  if ((simt_to_mem && get_is_write()) || !(simt_to_mem || get_is_write()))
    sz = size();
  else
    sz = get_ctrl_size();

  return (sz / icnt_flit_size) + ((sz % icnt_flit_size) ? 1 : 0);
}
